package com.leyou.item.servcie.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.leyou.common.dto.PageDTO;
import com.leyou.common.exceptions.LyException;
import com.leyou.item.entity.Category;
import com.leyou.item.entity.Sku;
import com.leyou.item.entity.Spu;
import com.leyou.item.entity.SpuDetail;
import com.leyou.item.mapper.SpuMapper;
import com.leyou.item.servcie.*;
import com.leyou.pojo.dto.QueryPageDto;
import com.leyou.pojo.dto.SkuDto;
import com.leyou.pojo.dto.SpuDetailsDto;
import com.leyou.pojo.dto.SpuDto;
import org.apache.commons.lang.StringUtils;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.leyou.common.constants.MQConstants.ExchangeConstants.ITEM_EXCHANGE_NAME;
import static com.leyou.common.constants.MQConstants.RoutingKeyConstants.ITEM_UP_KEY;
import static com.leyou.common.constants.MQConstants.RoutingKeyConstants.ITEM_DOWN_KEY;

@Service
public class SpuServiceImpl extends ServiceImpl<SpuMapper, Spu> implements SpuService {


    @Autowired
    private BrandService brandService;
    @Autowired
    private CategoryService categoryService;
    @Autowired
    private SpuDetailService spuDetailService;
    @Autowired
    private SkuService skuService;
    @Autowired
    private AmqpTemplate amqpTemplate;
    /**
     * 分页查询spu
     * @param queryPageDto
     * @return
     */
    @Override
    public PageDTO<SpuDto> queryGoodsByPage(QueryPageDto queryPageDto) {
        //首先查询spu，在根据分类id和品牌id查询分类和品牌名字
        //健壮性判断
        Math.max(1,queryPageDto.getPage());
        Math.max(1,queryPageDto.getRows());
        //分页查询spu
        Page<Spu> spuPage = query().eq(queryPageDto.getBrandId()!=null,"brand_id", queryPageDto.getBrandId())
                .eq(queryPageDto.getCategoryId()!=null,"cid3", queryPageDto.getCategoryId())
                .eq(queryPageDto.getId()!=null,"id", queryPageDto.getId())
                .eq(queryPageDto.getSaleable()!=null,"saleable", queryPageDto.getSaleable())
                .page(new Page<>(queryPageDto.getPage(), queryPageDto.getRows()));
        //转换dto
        List<SpuDto> spuDtoList = spuPage.getRecords().stream().map(SpuDto::new).collect(Collectors.toList());

        //查询品牌名称和分类名称
        for (SpuDto spuDto : spuDtoList) {
            queryCategoryNameAndBrandName(spuDto);
        }

        return new PageDTO<>(spuPage.getTotal(),spuPage.getPages(),spuDtoList);
    }

    /**
     * 新增商品
     * @param spuDto
     */
    @Override
    @Transactional
    public void saveGoods(SpuDto spuDto) {
        //装换dto
        Spu spu = spuDto.toEntity(Spu.class);
        SpuDetail spuDetail = spuDto.getSpuDetail().toEntity(SpuDetail.class);
        List<Sku> skuList = spuDto.getSkus().stream().map(skuDto -> skuDto.toEntity(Sku.class)).collect(Collectors.toList());
        //新增spu
        boolean b1 = save(spu);
        if (b1==false){
            throw new LyException("新增spu失败",500);
        }
        //新增spuDetail
        boolean b2 = spuDetailService.save(spuDetail);
        if (b2==false){
            throw new LyException("新增spuDetail失败",500);
        }

        //新增sku
        boolean b3 = skuService.saveBatch(skuList);
        if (b3==false){
            throw new LyException("新增sku失败",500);
        }


    }

    /**
     * 更改商品的上下架状态
     * @param spuId
     * @param saleable
     */
    @Override
    public void updateSaleable(Long spuId, Boolean saleable) {
        //数据库中涉及上下架的表共有两个，分别是spu，和sku，所以要分别修改两张表
        //更改spu表的上下架状态
        boolean success = update().set("saleable", saleable).eq("id", spuId).update();
        if(!success){
            throw  new LyException("修改spu表的上下架状态失败",500);
        }
        //修改sku表的saleable状态
         success = skuService.update().set("saleable", saleable).eq("spu_id", spuId).update();
        if(!success){
            throw new LyException("修改sku表的上下架状态失败",500);
        }
        if(saleable){
            //上架
            amqpTemplate.convertAndSend(ITEM_EXCHANGE_NAME,ITEM_UP_KEY,spuId);
        }else {
            //下架
            amqpTemplate.convertAndSend(ITEM_EXCHANGE_NAME,ITEM_DOWN_KEY,spuId);
        }
    }

    /**
     * 更新商品
     * @param spuDto
     */
    @Override
    @Transactional
    public void updateGoods(SpuDto spuDto) {
        //更新商品设计三个表，spu，sku，spuDetail
        //先判断spu表是否存在，存在更改，不存在，不更改,根据id判断
        if(spuDto.getId()!=null){
            Spu spu = spuDto.toEntity(Spu.class);
            //确保不更新saleable\
            spu.setSaleable(null);
            boolean success = updateById(spu);
            if (success==false){
                throw new LyException("更改spu表失败",500);
            }
        }
        //在判断spuDetail表是否存在，存在修改，不存在不修改
        SpuDetailsDto spuDetailDao = spuDto.getSpuDetail();
        if(spuDetailDao!=null&&spuDetailDao.getSpuId()!=null){
            SpuDetail spuDetail = spuDetailDao.toEntity(SpuDetail.class);
            spuDetailService.updateById(spuDetail);
        }
        //在判断sku表是否存在，存在修改，不存在不修改
        List<SkuDto> skus = spuDto.getSkus();
        if(CollectionUtils.isEmpty(skus)){
            return;
        }
//        //sku表涉及到增加，删除，更改操作，增加和修改可以一起，删除单独放在一起
//        List<Sku> skuList = skus.stream().map(skuDto -> skuDto.toEntity(Sku.class)).collect(Collectors.toList());
//        //遍历skuList
//        for (Sku sku : skuList) {
//            Boolean saleable = sku.getSaleable();
//            //判断saleable是否存在且等于false，是，删除
//            if(saleable!=null&&saleable==false){
//                boolean b = skuService.removeById(sku.getId());
//                if(b==false){
//                    throw new LyExceptions("删除sku表失败",500);
//                }
//            }else{
//                //不是增加或保存
//                boolean b = skuService.saveOrUpdate(sku);
//                if(b==false){
//                    throw new LyExceptions("增加或更改失败",500);
//                }
//            }
//        }
        //按照是否存在saleable分组
        Map<Boolean, List<Sku>> listMap = skus.stream().map(skuDto -> skuDto.toEntity(Sku.class))
                //判断是否存在saleable进行分组
                .collect(Collectors.groupingBy(sku -> sku.getSaleable()!=null));
        //saleable为true。说明包含saleable，进行删除操作
        List<Sku> skuList = listMap.get(true);
        //判断是否为空
        if(!CollectionUtils.isEmpty(skuList)){

            //按照id批量删除
            List<Long> longList = skuList.stream().map(Sku::getId).collect(Collectors.toList());
            boolean b = skuService.removeByIds(longList);
            if(b==false){
                throw new LyException("删除sku表失败",500);
            }
        }
        //saleable为false。保存和更改操作
        List<Sku> list = listMap.get(false);
        //判断是否为空，不为空，进行保存和更改操作
        if(CollectionUtils.isEmpty(list)==false) {
            //批量操作
            boolean b1 = skuService.saveOrUpdateBatch(list);
            if (b1 = false) {
                throw new LyException("增加或更改失败", 500);
            }
        }
    }

    /**
     * 查询spu，sku，spuDetail
     * @param spuId
     * @return
     */
    @Override
    public SpuDto querySkuAndSpuAndSpuDetail(Long spuId) {
        //查询spu
        Spu spu = getById(spuId);

        if(spu==null){
            throw new LyException("查询的商品不存在",500);
        }
        //转换成spuDto
        SpuDto spuDto = new SpuDto(spu);
        //注入商品分类名称和品牌名称
        queryCategoryNameAndBrandName(spuDto);
        //查询spuDetail
        SpuDetail spuDetail = spuDetailService.getById(spuId);
       if(spuDetail!=null){
           //转换成dto并注入spuDto
           spuDto.setSpuDetail(new SpuDetailsDto(spuDetail));
       }
        //查询sku
        List<Sku> skuList = skuService.query().eq("spu_id", spuId).list();
       if(CollectionUtils.isEmpty(skuList)==false){
           //转换成list并注入dto
           List<SkuDto> skuDtoList = skuList.stream().map(SkuDto::new).collect(Collectors.toList());
           spuDto.setSkus(skuDtoList);
       }
        return spuDto;
    }

    /**
     * 查询分类和品牌名字
     * @param spuDto
     */
    @Override
    public void queryCategoryNameAndBrandName(SpuDto spuDto) {
        //查询品牌名字
        String brandName = brandService.getById(spuDto.getBrandId()).getName();
        if(StringUtils.isNotBlank(brandName)){
            spuDto.setBrandName(brandName);
        }
        //查询分类名字
        List<Long> longList = Arrays.asList(spuDto.getCid1(), spuDto.getCid2(), spuDto.getCid3());
        //批量查询
        List<Category> categories = categoryService.listByIds(longList);
        if (CollectionUtils.isEmpty(categories)==false){
            //字符串拼接
            String categoryName = categories.stream().map(Category::getName).collect(Collectors.joining("/"));
            spuDto.setCategoryName(categoryName);
        }
    }



}
